package com.richapp.launcher.serialport.infrared.message;

import android.util.Log;

import com.richapp.launcher.gpio.GPIOServer;
import com.richapp.launcher.serialport.infrared.InfraredServer;
import com.richapp.launcher.serialport.infrared.abstracts.AMessage;
import com.richapp.net.util.HexTool;

import java.io.IOException;
import java.nio.ByteBuffer;

/**
 * Created by jack on 2015/4/3 0003.
 */
public class StudyMessage extends AMessage {

    /**
     * 设备类型 一个字节
     * 0x01 电视机
     * 0x02 网络电视
     * 0x03 机顶盒
     * 0x04 网络盒子
     * 0x05 空调
     * 0x06 DVD
     * 0x07 电风扇
     * 0x08 单反
     * 0x09 音箱
     * 0x0A 投影仪
     * 0x30 学习的数据
     */
    private byte deviceType = 0x30;

    /**
     * 按钮ID 一个字节
     * 0x00 - 0xFF
     */
    private byte buttonId = 0x00;

    private byte[] actionResult = null;
    private byte[] result = null;
    private byte[] head = null;
    private byte[] dataBuffer;

    public static final int TIME_OUT_STUDY = 1000 * 10;

    private long studyKey = 0;
    private String userName;

    public StudyMessage(){

    }

    @Override
    public void doCheckData() {
        setLength(HexTool.HexToByteArr("0002"));
        int check = getType();
        for(byte b : getLength()){
            check += b;
        }
        check = check + getDeviceType() + getButtonId();

        setCheck((byte)check);


        ByteBuffer byteBuffer = ByteBuffer.allocate(2);
        byteBuffer.put(deviceType);
        byteBuffer.put(buttonId);

        byte[] array = byteBuffer.array();
        setSendData(array);

        byteBuffer = ByteBuffer.allocate( 1 + 2 + array.length + 1 );
        byteBuffer.put(getType());
        byteBuffer.put(getLength());
        byteBuffer.put(array);
        byteBuffer.put(getCheck());

        array = byteBuffer.array();
        Log.d("DEBUG", "合成的数据:" + HexTool.ByteArrToHex(array));
        setAllData(array);
    }

    @Override
    public void doSendData() {
        try {
            Log.d("DEBUG","写入红外学习数据");
            getDataOutputStream().write(getAllData());
            getDataOutputStream().flush();
            setStartTime(System.currentTimeMillis());
            doGetResult();
        } catch (IOException e) {
            Log.d("DEBUG", "红外学习写入错误:" + e.getMessage());
        }
    }

    @Override
    public void doGetResult() {
        try{
            if(actionResult == null){
                if(getDataInputStream().available() > 4){
                    actionResult = new byte[5];
                    getDataInputStream().read(actionResult);
                    int check = 0;
                    for(int i = 0; i < actionResult.length-1 ;i++){
                        check += actionResult[i];
                    }
                    Log.d("DEBUG","红外学习反馈头数据:"+HexTool.ByteArrToHex(actionResult));
                    if(check != actionResult[4]){
                        Log.d("DEBUG", "红外学习反馈头校验失败:"+ "checkValue:"+check+ "|lastByte:"+actionResult[4]);
                    }else{
                        GPIOServer.getInstance().infraredStudyStart();
                    }
                }
            }else{
                if(head == null){
                    if(getDataInputStream().available() > 4){
                        head = new byte[5];
                        getDataInputStream().read(head);

                        byte[] len = new byte[2];
                        len[0] = head[1];
                        len[1] = head[2];

                        setLength(len);

                        dataBuffer = new byte[(HexTool.HexToInt(HexTool.ByteArrToHex(len)) - 2 + 1)];
                    }
                }else{
                    if(getDataInputStream().available() > dataBuffer.length-1){
                        getDataInputStream().read(dataBuffer);

                        ByteBuffer buffer = ByteBuffer.allocate(head.length+dataBuffer.length);
                        buffer.put(head);
                        buffer.put(dataBuffer);

                        byte[] array = buffer.array();

                        //检查校验
                        int checkLen = 0;
                        for(int i = 0 ; i < array.length-1 ; i++){
                            checkLen += array[i];
                        }
                        checkLen = checkLen % 256;
                        Log.d("DEBUG","红外学习反馈数据:"+HexTool.ByteArrToHex(array));
                        int lastByte = HexTool.HexToInt(HexTool.Byte2Hex(array[array.length-1]));
                        if(checkLen != lastByte){
                            Log.d("DEBUG", "红外学习读取校验失败:"+ "checkValue:"+checkLen+ "|lastByte:"+lastByte);
                        }
                        setResult(array);
                        setStopTime(System.currentTimeMillis());
                        final StudyMessage studyMessage = this;
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                getInfraredMessageListener().onInfraredMessage(studyMessage);
                            }
                        }).start();
                        GPIOServer.getInstance().infraredStudySuccessed();

                        /*ByteBuffer testBuffer = ByteBuffer.allocate(dataBuffer.length-1);
                        testBuffer.put(dataBuffer,0,dataBuffer.length-1);

                        testInfraredSendStudy(testBuffer.array());*/
                    }
                }
            }
        }catch (Exception e){
            Log.d("DEBUG", "红外学习读取错误:" + e.getMessage());
        }
    }

    @Override
    public boolean isTimeOut() {
        long currentTime = System.currentTimeMillis();
        long value = currentTime - getStartTime();
        boolean flag = value > TIME_OUT_STUDY;
        if(flag){
            Log.d("DEBUG", "红外学习发射超时");
            GPIOServer.getInstance().infraredStudyFailed();
        }
        return flag;
    }

    @Override
    public boolean isResultOk() {
        if(getResult() != null){
            return true;
        }
        return false;
    }


    public byte getDeviceType() {
        return (byte)0x30;
    }

    public void setDeviceType(byte deviceType) {
        this.deviceType = deviceType;
    }

    public byte getButtonId() {
        return buttonId;
    }

    public void setButtonId(byte buttonId) {
        this.buttonId = buttonId;
    }

    @Override
    public byte getType() {
        return 0x02;
    }

    public byte[] getResult() {
        return result;
    }

    public void setResult(byte[] result) {
        this.result = result;
    }

    public byte[] getActionResult() {
        return actionResult;
    }

    public void setActionResult(byte[] actionResult) {
        this.actionResult = actionResult;
    }

    public byte[] getHead() {
        return head;
    }

    public void setHead(byte[] head) {
        this.head = head;
    }

    public byte[] getDataBuffer() {
        return dataBuffer;
    }

    public void setDataBuffer(byte[] dataBuffer) {
        this.dataBuffer = dataBuffer;
    }

    public long getStudyKey() {
        return studyKey;
    }

    public void setStudyKey(long studyKey) {
        this.studyKey = studyKey;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    private void testInfraredSendStudy(byte[] controlData1){
        final byte[] controlData2 = controlData1;
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    Thread.sleep(10*1000);
                    ControlMessage controlMessage = new ControlMessage();
                    controlMessage.setDeviceType((byte)0x30);
                    controlMessage.setDeviceId((byte)0x01);
                    controlMessage.setControlData(controlData2);
                    int length = controlData2.length + 2;
                    String lengthStr = null;
                    if(length > 255){
                        lengthStr = Integer.toHexString(length);
                    }else{
                        lengthStr = "00" + Integer.toHexString(length);
                    }

                    controlMessage.setLength(HexTool.HexToByteArr(lengthStr));
                    InfraredServer.getInstance().send(controlMessage);
                }catch (Exception e){
                    Log.d("DEBUG", "自动测试错误:"+e.getMessage());
                }
            }
        }).start();

    }
}
